home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "../misc/misc.h"
- #include "../netconf/netconf.h"
- #include "fstab.h"
- #include "fstab.m"
-
- /*
- describe one entry of the partition table
- */
- PUBLIC PARTITION::PARTITION(
- const char *_dev,
- int _id,
- long _size)
- {
- dev =strdup_err(_dev);
- id = _id;
- size = _size;
- drive_letter = ' ';
- }
-
- PUBLIC PARTITION::~PARTITION()
- {
- free (dev);
- }
-
- /*
- Set the drive letter DOS would normally associate with this
- partition.
- */
- PUBLIC void PARTITION::setdosdrive(char letter)
- {
- drive_letter = letter;
- }
- /*
- Get the drive letter DOS would normally associate with this
- partition.
- */
- PUBLIC char PARTITION::getdosdrive()
- {
- return drive_letter;
- }
-
- /*
- Return != 0 if the partition is a DOS one.
- */
- PUBLIC int PARTITION::isdos()
- {
- return id == PARTITION_DOS_ID12
- || id == PARTITION_DOS_ID16
- || id == PARTITION_DOS_ID1632;
- }
- /*
- Return != 0 if the partition is a OS/2 one.
- */
- PUBLIC int PARTITION::isos2()
- {
- return id == PARTITION_OS2_HPFS;
- }
-
- /*
- Return != if a partition is a swap.
- */
- PUBLIC int PARTITION::isswap()
- {
- return id == PARTITION_LINUX_SWAP;
- }
- /*
- Return != if a partition is a native linux one (ext2).
- */
- PUBLIC int PARTITION::islinux()
- {
- /* #Specification: fsconf / partition / linux native
- fsconf does not differentiate minix / xiafs / ext and
- ext2 partition. It assumes that a "Linux native"
- partition is always a ext2 one.
- */
- return id == PARTITION_LINUX_NATIVE;
- }
-
-
- /*
- Return the path of the device controlling a partition.
- */
- PUBLIC const char *PARTITION::getdevice()
- {
- return dev;
- }
-
- /*
- Return the size (in block) of the partition
- */
- PUBLIC long PARTITION::getsize()
- {
- return size;
- }
-
- /*
- Return the ID (in block) of the partition
- */
- PUBLIC int PARTITION::getid()
- {
- return id;
- }
-
- PUBLIC void PARTITION::formatinfo(char *buf)
- {
- char drive[3];
- drive[0] = '\0';
- if (drive_letter != ' '){
- sprintf (drive,"%c:",drive_letter);
- }
- sprintf (buf,"%7ldM %-5s(%02x) %s"
- ,size/1024,getos()
- ,id,drive);
- }
-
- /*
- Return the name of the OS related to this partition if it is a
- filesystem.
-
- Return "" is unknown
- */
- PUBLIC const char *PARTITION::getos()
- {
- char *ret = "";
- if (isdos()){
- ret = "Dos";
- }else if (islinux()){
- ret = "Linux";
- }else if (isswap()){
- ret = "Swap";
- }else if (isos2()){
- ret = "Os/2";
- }
- return ret;
- }
-
- PUBLIC PARTITIONS::PARTITIONS()
- {
- DAEMON *dae = daemon_find ("fdisk");
- if (dae != NULL){
- char cmd[200];
- sprintf (cmd,"%s -l",dae->getpath());
- FILE *fin = popen (cmd,"r");
- if (fin != NULL){
- char buf[300];
- while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
- if(buf[0] == '/'){
- char t[7][30];
- int nb = sscanf (buf
- ,"%s %s %s %s %s %s %s"
- ,t[0],t[1],t[2],t[3],t[4],t[5]
- ,t[6]);
- if (nb != 7){
- xconf_error (
- MSG_U(E_IVLDFDISK
- ,"Invalid output format for fdisk\n%s")
- ,buf);
- }else{
- int offset = 4;
- if(strcmp(t[1],"*")==0) offset = 5;
- int id;
- sscanf (t[offset+1],"%x",&id);
- add (new PARTITION(t[0],id
- ,atoi(t[offset])));
- }
- }
- }
- }
- pclose (fin);
- }
- setdosdrive();
- }
-
- PUBLIC PARTITION *PARTITIONS::getitem(int no) const
- {
- return (PARTITION*)ARRAY::getitem(no);
- }
-
- /*
- Locate one partition in the table using its device path as key.
- Return NULL if not found.
- */
- PUBLIC PARTITION *PARTITIONS::getitem(const char *device) const
- {
- PARTITION *ret = NULL;
- for (int i=0; i<getnb(); i++){
- PARTITION *p = getitem(i);
- if (strcmp(p->getdevice(),device)==0){
- ret = p;
- break;
- }
- }
- return ret;
- }
-
- /*
- Assign DOS drive letter to DOS partition
- */
- PROTECTED void PARTITIONS::setdosdrive()
- {
- /* #Specification: partitions / dos drive / how it works
- All this is very complicate.
-
- DOS allocate C on the first non extended DOS partition
- of the first drive.
-
- It then allocate D if possible on the first non extended
- DOS partition of the second drive.
-
- From there is get back to the first drive and allocate
- a letter to all DOS extended partition. After that
- it goes and finished the second hard drive.
-
- I have no idea what happen when you get more than
- four drives. DOS does not support it if I am right.
- Some info is needed here.
- */
- char drive = 'C';
- char minpart = '1';
- char maxpart = '4';
- for (int pass=0; pass<2; pass++){
- for (int d='a'; d<='b'; d++){
- for (int i=minpart; i<=maxpart; i++){
- char buf[10];
- sprintf (buf,"/dev/hd%c%c",d,i);
- PARTITION *p = getitem (buf);
- if (p != NULL
- && p->isdos()){
- p->setdosdrive(drive);
- drive++;
- if (pass == 0) break;
- }
- }
- }
- minpart = '5';
- maxpart = '8';
- }
- }
-
- /*
- Probe the partition table of all devices.
- This take some time since fdisk is spawned to get it. So the
- result is kept from call to call.
-
- The returned object should not be deleted.
- */
- PARTITIONS *partition_load()
- {
- static PARTITIONS *parts = NULL;
- if (parts == NULL){
- parts = new PARTITIONS;
- }
- return parts;
- }
-
- #ifdef TEST
-
- int main (int , char *[])
- {
- PARTITIONS parts;
- for (int i=0; i<parts.getnb(); i++){
- PARTITION *p = parts.getitem(i);
- char *type = "???";
- if (p->isswap()){
- type = "Swap";
- }else if (p->isdos()){
- type = "Dos";
- }else if (p->islinux()){
- type = "Linux";
- }
- printf ("%s %ld %s\n",p->getdevice(),p->getsize()
- ,type);
- }
- return 0;
- }
-
- #endif
-